;BYSTRETKA MIĘSOŻERNA
;ZYWI SIE WORMSAMI
;UCIEKA PRZED DRAPIEZNIKAMI i ZABIJA JE


;-----------------------------------------------------------------------------
	;używane deftemplate'y
	
(deftemplate visible (slot Object) (slot PosX) (slot PosY)) 
(deftemplate field (slot Type) (slot Resource) (slot PosX) (slot PosY)) 
(deftemplate stat (slot Name) (slot Value))	
	;zwracane
(deftemplate move (slot Move) (slot MoveX) (slot MoveY))
	;lokalne

 (deftemplate musiszJesc (slot Kiedy)) 
 (deftemplate najlepszeZarcie (slot Resource) (slot PosX) (slot PosY))
 

;-----------------------------------------------------------------------------   
;-----------------------------------------------------------------------------
;					JEDZENIE I SPRAWDZENIE, CZY ZNALAZŁA ROBAKA
;-----------------------------------------------------------------------------   
;-----------------------------------------------------------------------------

;musi zacząć interesować się jedzeniem, jeśli ma mało zapasów(najedzenia)
 
 (defrule czyMusiJesc
 (stat (Name food) (Value ?v) )				; jeśli ma mniej niż 5 żarełka, to zaznacza, że musi jeść
	(test (< ?v 20))
	=>
	(bind ?kiedy (- ?v 1))
	(assert (musiszJesc (Kiedy ?kiedy))))
	
;-----------------------------------------------------------------------------

; koniecznie musi coś zjeść, jeśli jest osłabiony i akurat trafił na robaka
(defrule jedzNatychmiast
	(field (Type WORM) (Resource ?r) (PosX 0) (PosY 0))				; stoi na polu z robakiem i musi jeść natychmiast (kiedy==0)
 	(musiszJesc (Kiedy ?kiedy))
 	(test (< ?kiedy 5))
 	=>
 	(assert (move (Move collectWorm)(MoveX 0) (MoveY 0) )))
 	
;-----------------------------------------------------------------------------
; jeśli ma jeszcze troszkę zapasu, może iść szukać lepszych źródeł jedzenia

(defrule szukajDobregoJedzenia
  	(musiszJesc (Kiedy ?kiedy))			
  	(test (< ?kiedy 15)
  		)
  	=>
  	(assert (najlepszeZarcie (Resource 0) (PosX 0) (PosY 0))))

;-----------------------------------------------------------------------------
;

(defrule najlepszeZrodloJedzenia										; gniazdo roboków!
  	?gniazdo <- (field (Type WORM) (Resource ?r) (PosX ?x) (PosY ?y))
  	?najlepszy <-  (najlepszeZarcie  (Resource ?rB) (PosX ?xB) (PosY ?yB))
  	(test (< ?rB ?r))													;jeśli zasoby najlepszego sa mniejsze niż te w gnieździe
  	=>
  	(retract ?najlepszy)
  	(assert (najlepszeZarcie (Resource ?r) (PosX ?x) (PosY ?y))))		; ustawiamy, że najlepsze żarcie jest w aktualnym polu.
 
 ;----------------------------------------------------------------------------- 	
 
 ;;;; nasza bystretka stoi w punkcie 0,0. Naokoło ma punkty -1,0; 1,0; 0,-1; 0,1 ; -1,-1; -1,1; 1,-1; 1,1
 ;;;; poniższe dwie funkcje powodują przemieszczenie się do najlepszego miejsca z jedzeniem
 ;;;; zlokalizowanego w którymś z tych czterech punktów.
 ;;;; (test (> ?x ?y)) sprawdza czy x>y, czyli punkty 1,0,  0,1, 1,-1
 ;;;; (test (>= ?y ?x)) sprawdza y >=x, czyli  0,-1 ; -1,-1; -1,1; 1,1; 0,0
 ;;;; np jeśli x!=0 to  ( x / |x|) * (-1) dla ujemnych x pokazuje, że musimy iść o x=+1; dla dodatnich - o -1
 
 
 
    (defrule idzDoNajlepszegoX
  	(najlepszeZarcie (Resource ?r) (PosX ?x) (PosY ?y))					;sprawdzamy położenie najlepszego punktu z jedzeniem
  	(test (> ?x ?y))													; 
  	=>
  	(if (not (= ?x 0) ) then											; jeśli x jest rózny od 0
	(bind ?nowyX (* -1 (/ ?x (abs ?x))))								; nowy x ustawiamy na ( x / |x|) * (-1) - czyli 1 lub -1
	)
	(if (= ?x 0 ) then													; jeśli x=0, pozostaje 0
		(bind ?nowyX 0)
	)
    (assert (move (Move move)(MoveX ?nowyX) (MoveY 0) )))
 
 ;-----------------------------------------------------------------------------   
    (defrule idDoNajlepszegoY
  	(najlepszeZarcie (Resource ?r) (PosX ?x) (PosY ?y))
  	(test (>= ?y ?x))
  	=>
	(if (not (= ?y 0) ) then
	(bind ?nowyY (* -1 (/ ?y (abs ?y))))
	)
	(if (= ?y 0) then
		(bind ?nowyY 0)
	)
    (assert (move (Move move)(MoveX 0) (MoveY ?nowyY) )))



;-----------------------------------------------------------------------------   
;-----------------------------------------------------------------------------
;						ZABAWA Z DRAPIEŻNIKAMI
;-----------------------------------------------------------------------------   
;-----------------------------------------------------------------------------

(defrule zabijDrapieznika
	(visible (Object DRAPIEZNIK) (PosX ?x) (PosY ?y) )
	=>
	(assert (move (Move kill) (MoveX ?x) (MoveY ?y) ) )
)


